package com.mercycrazy.recruit.config;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.net.InetAddress;

import static com.mercycrazy.recruit.constant.CommonConstant.GATEWAY_SERVICE_ID;

/**
 * Knife4j 底层依赖于 Spring Doc, 配置类
 *
 * @author <a href="mailto:1443424326@qq.com">mercycrazy</a>
 * @since 2023-01-13
 */
@Slf4j
@SuppressWarnings("all")
@Configuration
@OpenAPIDefinition(
        info = @Info(
                title = "boss-recruit-service",
                description = "boss recruit service api document",
                version = "v1.0.0",
                contact = @Contact(
                        name = "mercycrazy",
                        url = "https://mercycrazy.com",
                        email = "1443424326@qq.com"
                )
        )
)
public class SpringDocConfig {

    @Value("${server.servlet.context-path}")
    private String currentServiceContextPath;

    @Value("${server.port}")
    private int currentServicePort;

    @Resource
    private LoadBalancerClient loadBalancerClient;

    @Bean
    public GroupedOpenApi groupedOpenApi() {
        return GroupedOpenApi.builder()
                .group("default")
                .pathsToMatch("/**")
                .build();
    }

    /**
     * 启动时打印 API 文档访问地址
     */
    @PostConstruct
    public void logAccessUrl() {

        String host;
        int port;

        ServiceInstance serviceInstance = loadBalancerClient.choose(GATEWAY_SERVICE_ID);

        // gateway 未启动, 降级打印本地 API 文档地址
        if (null == serviceInstance) {
            try {
                log.warn("can not find gateway instance, please check gateway has been started!");
                port = currentServicePort;
                host = InetAddress.getLocalHost().getHostAddress();
            } catch (Exception ex) {
                log.error("get local host failed: [{}]", ex.getMessage(), ex);
                return;
            }
        } else {

            log.info("get gateway service instance info from nacos, serviceId: [{}], instanceId: [{}], metadata: [{}]",
                    serviceInstance.getServiceId(), serviceInstance.getInstanceId(), serviceInstance.getMetadata());

            host = serviceInstance.getHost();
            port = serviceInstance.getPort();
        }

        currentServiceContextPath = fixPath(currentServiceContextPath);

        String accessUrl = String.format("http://%s:%s/%s/doc.html",
                host, port, currentServiceContextPath);

        log.info("======================= api doc access url ========================");
        log.info("======================= {} ========================", accessUrl);
    }

    /**
     * 去掉路径开头的 "/"
     */
    private String fixPath(String path) {
        return path.startsWith("/") ? path.replace("/", "") : path;
    }
}
